[第十六週]從簡單例子了解 closure (閉包)


Posted by Powerfultraveling 's Blog on 2021-07-31

前言

這篇文章主要是用來記錄理解 closure 的過程,scope 其實沒有很難懂的理論,但是整體非常的複雜,如果沒有專心推演每一個環節得話,像我這樣的初學者很容易小迷路。我也是這樣過來的,最後發現 Huli 老師在課堂中用的這段程式碼還蠻適合理解基礎的 closure 概念的,但是腦袋容量有限,想趁腦袋還搞得清楚時來記錄理解 closure 的推演邏輯。

以下就是本文章所要使用的程式碼:

function test(){
    var a = 10;
    function inner(){
        console.log(a);
    }
    return inner
}
var func = test();

假裝你是 JavaScript 引擎

在接下來,我們會以自己是 JavaScript 引擎的角度,一步步建構各層的 execution context 還有 variable object(在 function 裡面的要改名叫 object,雖然兩個基本上是一樣的東西)。

global

  1. 引擎進到 global 的範圍裡,先找看看有沒有 variables 和 function。
  2. 找到了 function test() 以及變數 func,把他們兩個加進 variables object。
//object 裡面大概會長這樣
global{
    variables object{
        test: function,
        func: undefined
    }
}
  1. 程式開始執行,function test() 還未被呼叫先跳過。
  2. var func = test(); test() 被呼叫,進入 test() 的範圍裡。v

function test()

  1. 進到 test() 的範圍裡,尋找看看有沒有 variables 或 function。
  2. 找到了 variable a 以及 function inner(),將他們加進 variable object 裡面。
//variable object 裡面大概長這樣
test{
    variable object{
        a: undefined,
        inner: function
    }
}

執行之後:

test{
    variable object{
    a: 10,
    inner: function
    }
}
  1. test() 返回 inner() function。
  2. 回到 global。

global

  1. 變數 func 等於 test() 回傳的 function inner()
  2. test() function 執行結束,所以 test() 裡的 variable object 和 execution context 需要移除 -> X
  3. 因為 global 裡面的變數 func 等於 test() 裡面的 inner(),在未來如果呼叫了 func 會用到 inner()test() 裡的 variable object。所以 test()inner() 的 variable object 會被存下來,以備不時之需。

用 node.js 的環境執行後,可以發現的確如上面所述,變數 a 的 變化全部都被引擎記下來,並沒有因為引擎已經跑完 test() 的環境而刪掉這些資訊。

這就是 closure 的行為。










Related Posts

期末專案規劃

期末專案規劃

Linux kernel feature

Linux kernel feature

Deep Learning on 3D object detection paper 閱讀路徑

Deep Learning on 3D object detection paper 閱讀路徑


Comments